package com.xuxueli.applyModules.utils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xuxueli.applyModules.utils.exporttables.TestDoc;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Map;

/**
 * 生成byte[],解析数据,生成签名，解析签名，时间戳
 */
@Slf4j
public class TestCreateByteArray {

    public static void main(String[] args) {
        String exportDoc = TestDoc.exportDoc("D:\\data\\你好.doc");
        byte[] toByteArrays = toByteArray(exportDoc);
        byte[] readFile = readFile("D:\\data", "你好.doc");
        if (toByteArrays.equals(readFile)){
            System.out.println("生成规则一致");
        }
        System.out.println(toByteArrays);
        Object objectToBytes = toObjectType(toByteArrays);
        System.out.println(objectToBytes);
        Object objectToBytess = toObjectType(readFile);
        System.out.println(objectToBytess);
    }

    /**
     * 将Object对象转byte数组
     * @param obj byte数组的object对象
     * @return
     */
    public static byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray ();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }

    /**
     * 将byte数组转Object对象
     * @param bytes
     * @return
     */
    public static Object toObjectType(byte [] bytes){
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        Object object = null;
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(bis);
            object = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return object;
    }

    /**
     * 下载resources下文档
     */
    public static void downloadDocument(String classPath, OutputStream out) {
        ClassPathResource resource = new ClassPathResource(classPath);
        try (BufferedInputStream in = new BufferedInputStream(resource.getInputStream())) {
            byte[] bytes = new byte[1024];
            int len;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
            log.error("下载失败: {}", classPath);
        }
        log.info("下载成功: {}", classPath);
    }


    /**
     * 下载resources下文档
     */
    public static void downloadFile(String classPath, OutputStream out) throws FileNotFoundException {
        InputStream resource = new FileInputStream(new File(classPath));
        try (BufferedInputStream in = new BufferedInputStream(resource)) {
            byte[] bytes = new byte[1024];
            int len;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
            log.error("下载失败: {}", classPath);
        }
        log.info("下载成功: {}", classPath);
    }


    public static String getcontentType(String fileName){
        String contentType = new MimetypesFileTypeMap().getContentType(fileName);
        return contentType;
    }

    public static void responseWrite(Object result, HttpServletResponse response) {
        try (OutputStream out = response.getOutputStream()) {
            out.write(JSONObject.toJSONBytes(result, SerializerFeature.WriteMapNullValue));
            out.flush();
        } catch (IOException e) {
            log.error("文件流写失败", e);
        }
    }

    public static byte[] readFile(String path, String name) {
        File file = new File(path + File.separator + name);
        if (!file.exists()) {
            log.info("文件不存在,{}", name);
            return null;
        }
        try (BufferedInputStream in = new BufferedInputStream(
                new FileInputStream(file)); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            byte[] bytes = new byte[2048];
            int length;
            while ((length = in.read(bytes)) != -1) {
                out.write(bytes, 0, length);
            }
            out.flush();
            return out.toByteArray();
        } catch (IOException e) {
            log.error("下载文件异常", e);
        }
        return null;
    }

    public static void responseWrite(byte[] bodyBytes, HttpServletResponse response) {
        response.reset();
        response.setCharacterEncoding("UTF-8");
        try (ByteArrayInputStream in = new ByteArrayInputStream(bodyBytes); OutputStream out = response
                .getOutputStream()) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void responseWrite(InputStream in, HttpServletResponse response) {
        try (OutputStream out = response.getOutputStream()) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生签
     **/
    public static String createSignature(String secretKey, Map<String, Object> parameters, Long timestamp) {
        StringBuilder assemble = assembleParameters(parameters);
        assemble.append(timestamp).append(";").append(secretKey);
        String encrypt = MD5Util.md5Encode(assemble.toString());
        return encrypt;
    }

    /**
     * 验签
     **/
    public static boolean checkSignature(String secretKey, Map<String, Object> parameters, Long timestamp,
                                         String signature) {
        if (StringUtils.isBlank(secretKey) || StringUtils.isBlank(signature) || timestamp == null) {
            return false;
        }
        StringBuilder assemble = assembleParameters(parameters);
        assemble.append(timestamp).append(";").append(secretKey);
        String encrypt = MD5Util.md5Encode(assemble.toString());
        return encrypt.equals(signature);
    }

    /**
     * 校验时间戳在时间区间内
     */
    public static boolean checkTimeStampInPeriod(long timestamp) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, -15);
        long before = cal.getTime().getTime();
        Calendar cal2 = Calendar.getInstance();
        cal2.add(Calendar.MINUTE, 15);
        long after = cal2.getTime().getTime();
        return (before <= timestamp) && (timestamp <= after);
    }

    //组装服务参数
    public static <T> StringBuilder assembleParameters(Map<String, T> paramMap) {
        StringBuilder result = new StringBuilder();
        if (paramMap == null || paramMap.isEmpty()) {
            return result;

        }
        paramMap.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(entry ->
                result.append(entry.getKey()).append(":").append(entry.getValue()).append(":"));
        return result;
    }


}
